class Socket {
  wsData = null as any
  lockReconnect = false
  websocket = null as any
  heartInterval = null as any
  reconnectTimeout = null as any
  constructor(data) {
    if (!window.WebSocket) {
      console.error('您的浏览器不支持websocket')
      return
    }
    this.websocket = null
    this.wsData = data
    this.initSocket(data)
  }
  initSocket(data) {
    if (data?.url) {
      let url = data?.url
      if (!/^wss?:\/\//.test(data?.url)) {
        const { protocol } = window.location
        const handledUrl = data?.url.split('://')[1]
        url = protocol === 'http:' ? 'ws://' + handledUrl : 'wss://' + handledUrl
      }
      try {
        this.websocket = new WebSocket(url)
        this.websocket.onopen = (e) => {
          console.log('连接成功', e)
          this.websocket.send(JSON.stringify(this.wsData.params))
          if (data?.timer > 0) {
            this.heartCheck(data.timer)
          }
        }
        this.websocket.onmessage = (e) => {
          if (typeof data?.onmessage === 'function') {
            data.onmessage(e)
          }
        }
        this.websocket.onclose = (e) => {
          console.log('连接关闭', e)
          data?.reconnect && this.reconnect()
        }
      } catch (e) {
        data?.reconnect && this.reconnect()
      }
    }
  }

  send(data) {
    console.log('连接状态', this.websocket.readyState)
    if (!this.websocket || this.websocket.readyState !== 1) {
      console.log('请确认websocket是否已连接并且可以通讯')
      this.heartInterval && clearInterval(this.heartInterval)
      return
    }
    this.websocket.send(JSON.stringify(data))
  }

  close() {
    this.heartInterval && clearInterval(this.heartInterval)
    this.reconnectTimeout && clearInterval(this.reconnectTimeout)
    if (!this.websocket) {
      console.log('websocket 不可用')
      return
    }
    this.websocket.close()
    this.websocket = null
    console.log('websocket', this.websocket)
  }

  heartCheck(timer) {
    this.heartInterval = setInterval(() => {
      this.send(this.wsData?.params || {})
    }, timer)
  }

  reconnect() {
    if (this.lockReconnect) return
    this.lockReconnect = true
    this.reconnectTimeout && clearInterval(this.reconnectTimeout)
    this.reconnectTimeout = setTimeout(() => {
      this.initSocket(this.wsData)
      this.lockReconnect = false
    }, 5000)
  }
}

export default Socket
